function uuid() {
    function s4() {
        return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
    }
    return s4() + s4() + "-" + s4() + "-" + s4() + "-" + s4() + "-" + s4() + s4() + s4();
}

function HexToBase64(hex) {
    var base64Digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    var base64 = "";
    var group;
    for (var i = 0; i < 30; i += 6) {
        group = parseInt(hex.substr(i, 6), 16);
        base64 += base64Digits[(group >> 18) & 0x3f];
        base64 += base64Digits[(group >> 12) & 0x3f];
        base64 += base64Digits[(group >> 6) & 0x3f];
        base64 += base64Digits[group & 0x3f];
    }
    group = parseInt(hex.substr(30, 2), 16);
    base64 += base64Digits[(group >> 2) & 0x3f];
    base64 += base64Digits[(group << 4) & 0x3f];
    base64 += "==";
    return base64;
}

function NUUID(uuid) {
    var hex = uuid.replace(/[{}-]/g, ""); // remove extra characters
    var a = hex.substr(6, 2) + hex.substr(4, 2) + hex.substr(2, 2) + hex.substr(0, 2);
    var b = hex.substr(10, 2) + hex.substr(8, 2);
    var c = hex.substr(14, 2) + hex.substr(12, 2);
    var d = hex.substr(16, 16);
    hex = a + b + c + d;
    var base64 = HexToBase64(hex);
    return new BinData(3, base64);
}

ratings = db.CriteriaLevel2.findOne({ Name: 'Ratings' })
if (ratings) {
    db.CriteriaLevel2.update({ _id: ratings._id }, { $set: { Name: 'ESG Theme Ratings' } })
    db.CriteriaLevel2.insert({
        _id: NUUID(uuid()),
        CriteriaLevel1Id: ratings.CriteriaLevel1Id,
        Name: 'Overall ESG Ratings',
        UniverseFeature: NumberInt(ratings.UniverseFeature),
        ShortName: ratings.ShortName,
        Order: NumberInt(ratings.Order - 1)
    })
}

overallEsgRatings = db.CriteriaLevel2.findOne({Name: 'Overall ESG Ratings'})
if (overallEsgRatings) {
    names = ['Total ESG Score', 'ESG Performance Assessment', 'Comparative Group Average', 'Rank', 'Percentile']
    db.CriteriaLevel3.remove({ Name: { $in: names } })
    names.forEach(function (name, index) {
        var id = NUUID(uuid())
        db.CriteriaLevel3.insert({
            _id: id,
            Name: name,
            ShortName: '',
            Order: NumberInt(names.length - index),
            CriteriaLevel2Id: overallEsgRatings._id,
            Category: 'None'
        })
        db.TemplateCriteria.update({ Name: name }, { $set: {
            CriteriaLevel2Id: overallEsgRatings._id,
            CriteriaLevel3Id: id,
        }
        })
        db.OldTemplateCriteria.update({ Name: name }, { $set: {
            CriteriaLevel2Id: overallEsgRatings._id,
        } })
        db.FilterCriteria.update({ Name: name }, { $set: {
            CriteriaLevel2Id: overallEsgRatings._id,
            CriteriaLevel3Id: id,
        } })
    })

    totalEsgScore = db.CriteriaLevel3.findOne({Name: 'Total ESG Score'})
    if (!db.TemplateCriteria.findOne({Name: 'Total ESG Score'})) {
        db.TemplateCriteria.insert({
            _id: NUUID(uuid()),
            Name: 'Total ESG Score',
            CriteriaEntity: null,
            CriteriaEntityField: 'Total ESG Score',
            CriteriaLevel2Id: totalEsgScore.CriteriaLevel2Id,
            CriteriaLevel3Id: totalEsgScore._id,
            CriteriaType: NumberInt(6),
            IsScreenable: true
        })
    }
    if (!db.TemplateCriteria.findOne({Name: 'Research Type'})) {
        db.TemplateCriteria.insert({
            _id: NUUID(uuid()),
            Name: 'Research Type',
            CriteriaEntity: null,
            CriteriaEntityField: 'Research Type',
            CriteriaLevel2Id: totalEsgScore.CriteriaLevel2Id,
            CriteriaLevel3Id: totalEsgScore._id,
            CriteriaType: NumberInt(6),
            IsScreenable: false
        })
    }
  
    totalEsgPerformance = db.CriteriaLevel3.findOne({Name: 'ESG Performance Assessment'})
    if (!db.TemplateCriteria.findOne({Name: 'ESG Performance Assessment'})) {
        db.TemplateCriteria.insert({
            _id: NUUID(uuid()),
            Name: 'ESG Performance Assessment',
            CriteriaEntity: null,
            CriteriaEntityField: 'ESG Performance Assessment',
            CriteriaLevel2Id: totalEsgPerformance.CriteriaLevel2Id,
            CriteriaLevel3Id: totalEsgPerformance._id,
            CriteriaType: NumberInt(6),
            IsScreenable: false
        })
    }
}